﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using snat.algorithms;
using snat.model;

using algorithms.utils.resultsets;
using algorithms.utils.metrics;
using algorithms.utils.metrics.network;



namespace algorithms.algorithms.EdgeClusteringAlgorithm
{
    public class EdgeClustering : IWindowedAlgorithm, ITextRenderable
    {
        public event AlgorithmProcessed Processed;

        public Dictionary<int, HashSet<ClusterNode>> Clustering { get; private set; }

        public string Name {
            get { return "Edge Betweeness Clustering 2"; }
        }

        private void DoCluster() {
            FloydWarshall fw = new FloydWarshall();
            ResultMatrix<BaseNode> floydresult = fw.RunFW();
            Dictionary<Edge, int> edgescores = NodeBetweeness.ComputeEdgeBetweeness(floydresult);
            Dictionary<int, HashSet<ClusterNode>> clustering = ConnectedComponents.EdgeDelineatedClusters(edgescores, 5, 8);

            foreach (int clusterid in clustering.Keys) {
                foreach (OverlayNode o in clustering[clusterid]) {
                    if (o is ClusterNode) {
                        ClusterNode cn = o as ClusterNode;
                        cn.ClusterID = clusterid;
                    }
                }
            }
            Clustering = clustering;
        }

        public void Register() {
            NetworkModel.Instance.TapeEnded += DoCluster;
            NetworkModel.Instance.TapeEnded += ShowResult;
            
        }

        void ShowResult() {
            if(RenderText!= null) RenderText(this);
        }
        public void DeRegister() {
            NetworkModel.Instance.TapeEnded -= DoCluster;
            NetworkModel.Instance.TapeEnded -= ShowResult;
        }


        #region ITextRenderable Members

        public event RenderTextDelegate RenderText;

        public string GetRenderableText() {
            StringBuilder ret = new StringBuilder();
            IOrderedEnumerable<KeyValuePair<int,HashSet<ClusterNode>>> results = Clustering.ToList().OrderBy(e => e.Key);
            foreach (KeyValuePair<int,HashSet<ClusterNode>> kvp in results) {
                ret.Append("Cluster ");
                ret.Append(kvp.Key.ToString());
                ret.AppendLine(" members:");
                foreach (ClusterNode member in kvp.Value) {
                    ret.AppendLine("\t" + member.Name);
                }
            }

            


            return ret.ToString();
        }

        #endregion
    }
}
